/**
 * 
 */
package jface.viewers;

import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerRow;
import org.eclipse.swt.widgets.TableItem;

/**

 * 
 */
public class CellUtils {

	public static ViewerCell getNeighbor(ViewerCell currentCell,
			int directionMask, boolean sameLevel) {
		ViewerRow row;

		if ((directionMask & ViewerCell.ABOVE) == ViewerCell.ABOVE) {
			row = currentCell.getViewerRow().getNeighbor(ViewerRow.ABOVE,
					sameLevel);
		} else if ((directionMask & ViewerCell.BELOW) == ViewerCell.BELOW) {
			row = currentCell.getViewerRow().getNeighbor(ViewerRow.BELOW,
					sameLevel);
		} else {
			row = currentCell.getViewerRow();
		}

		if (row != null) {
			int columnIndex;
			columnIndex = getVisualIndex(row, currentCell.getColumnIndex());

			int modifier = 0;

			if ((directionMask & ViewerCell.LEFT) == ViewerCell.LEFT) {
				modifier = -1;
			} else if ((directionMask & ViewerCell.RIGHT) == ViewerCell.RIGHT) {
				modifier = 1;
			}

			columnIndex += modifier;

			if (columnIndex >= 0 && columnIndex < row.getColumnCount()) {
				ViewerCell cell = getCellAtVisualIndex(row, columnIndex);
				if (cell != null) {
					while (cell != null
							&& columnIndex < row.getColumnCount() - 1
							&& columnIndex > 0) {
						if (isVisible(cell)) {
							break;
						}

						columnIndex += modifier;
						cell = getCellAtVisualIndex(row, columnIndex);
						if (cell == null) {
							break;
						}
					}
				}

				return cell;
			}
		}
		return null;
	}

	// Reimplementation of ViewerCell-Methods
	private static int getVisualIndex(ViewerRow row, int creationIndex) {
		TableItem item = (TableItem) row.getItem();
		int[] order = item.getParent().getColumnOrder();

		for (int i = 0; i < order.length; i++) {
			if (order[i] == creationIndex) {
				return i;
			}
		}
		return creationIndex;
	}

	private static ViewerCell getCellAtVisualIndex(ViewerRow row,
			int visualIndex) {
		return getCell(row, getCreationIndex(row, visualIndex));
	}

	public static int getCreationIndex(ViewerRow row, int visualIndex) {
		TableItem item = (TableItem) row.getItem();
		if (item != null && !item.isDisposed() /*
												 * && hasColumns() &&
												 * isValidOrderIndex
												 * (visualIndex)
												 */) {
			return item.getParent().getColumnOrder()[visualIndex];
		}
		return visualIndex;
	}

	private static int getWidth(ViewerCell cell) {
		TableItem item = (TableItem) cell.getViewerRow().getItem();
		return item.getParent().getColumn(cell.getColumnIndex()).getWidth();
	}

	private static ViewerCell getCell(ViewerRow row, int index) {
		return row.getCell(index);
	}

	private static boolean isVisible(ViewerCell cell) {
		return getWidth(cell) > 0;
	}

}
